package com.xyy.saas.payment.callback.core.job;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.xyy.elasticjob.client.annotation.ElasticJobConf;
import com.xyy.saas.payment.cores.enums.ChannelEnum;
import com.xyy.saas.payment.dao.model.PayResultOrder;
import com.xyy.saas.payment.payment.core.service.ProfitSharingService;
import com.xyy.saas.payment.service.OrderService;
import com.xyy.saas.payment.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 小雨点支付放款成功后结算给商户
 * 每30分执行一次，捞2小时内的数据
 *
 * @author wangzeqi
 */
@Slf4j
@ElasticJobConf(name = "com.xyy.saas.payment.callback.core.job.XydCreditPaySettleJob", cron = "0 6/30 * * * ?")
public class XydCreditPaySettleJob implements SimpleJob {

    @Resource
    private OrderService orderService;
    @Resource
    private ProfitSharingService profitSharingService;
    @Resource
    private RedisUtil redisUtil;

    @Value("${xydCredit.paySettleJob.interrupt:false}")
    private Boolean interrupt;
    @Value("${xydCredit.paySettleJob.maxPages:}")
    private Integer maxPages;
    @Value("${xydCredit.paySettleJob.sleepTimeMillis:500}")
    private Long sleepTimeMillis;

    @Override
    public void execute(ShardingContext shardingContext) {
        log.info("###XydCreditPaySettleJob started...shardingContext = {}", JSON.toJSONString(shardingContext));

        try {

            int pageOffset = 0;
            int pageSize = 50;
            Date endDate = new Date();
            Date startDate = DateUtil.offsetHour(endDate, -2);

            while (true) {

                List<PayResultOrder> payResultOrderList = orderService.selectPayResultOrderListByCondition(null, null, null, null,
                        ChannelEnum.XYD_LOAN.getCode(), startDate, endDate, pageOffset * pageSize, pageSize);
                log.info("###XydCreditPaySettleJob execute payResultOrderList startDate={}, endDate={}, size={}",
                        com.xyy.saas.payment.util.DateUtil.format(startDate, com.xyy.saas.payment.util.DateUtil.DATEFORMATSECOND),
                        com.xyy.saas.payment.util.DateUtil.format(endDate, com.xyy.saas.payment.util.DateUtil.DATEFORMATSECOND),
                        payResultOrderList.size());

                if (CollectionUtil.isEmpty(payResultOrderList)) {
                    break;
                }

                for (PayResultOrder payResultOrder : payResultOrderList) {

                    try {
                        // 已结算过滤
                        String xydCreditPaySettleSucKey = RedisUtil.PREFIX_XYD_CREDIT_PAY_SETTLE_SUCCESS + payResultOrder.getPayNo();
                        if (redisUtil.exists(xydCreditPaySettleSucKey)) {
                            log.info("######XydCreditPaySettleJob 已结算成功过滤 {}", payResultOrder.getPayNo());
                            continue;
                        }

                        profitSharingService.xydCreditPaySettle(payResultOrder.getPayNo());
                    } catch (Exception e) {
                        log.error("###XydCreditPaySettleJob settle order error, {}", payResultOrder.getPayNo(), e);
                    }

                }

                if (Boolean.TRUE.equals(interrupt)) {
                    log.warn("###XydCreditPaySettleJob interrupt, current page:{}-{}", pageOffset, pageSize);
                    break;
                }

                if (payResultOrderList.size() < pageSize) {
                    break;
                }

                if (maxPages != null && pageOffset >= maxPages) {
                    log.info("###XydCreditPaySettleJob maxPages limit break, {}-{} lastPayNo:{}", pageOffset, pageSize,
                            payResultOrderList.get(payResultOrderList.size() - 1).getPayNo());
                    break;
                }

                pageOffset++;

                TimeUnit.MILLISECONDS.sleep(sleepTimeMillis);
            }
        } catch (Exception e) {
            log.error("###XydCreditPaySettleJob exec error ", e);
        }

    }

}
